﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Reflection;
/// <summary>
/// PropertyInfo扩展
/// </summary>
public static class ESF_PropertyInfoExtend
{
    /// <summary>
    /// 是否有ObsoleteAttribute属性
    /// </summary>
    /// <param name="_property">成员</param>
    /// <returns>true:有,false:无</returns>
    public static bool HasObsoleteAttribute(this PropertyInfo _property)
    {
        return _property.GetCustomAttribute<ObsoleteAttribute>() != null;
    }

    /// <summary>
    /// 获得属性CSharp访问关键字
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>CSharp关键字</returns>
    public static string GetCSharpAccessKeyword(this PropertyInfo _property)
    {
        string keyword = string.Empty;
        if (_property.PropertyType.IsNestedPrivate)
        {
            keyword = enESF_CSharpKeyword.privateKeyword.ESF_FirstAttribute<ESF_AliasTooltipAttribute>().alias;
        }
        else if (_property.PropertyType.IsPublic)
        {
            keyword = enESF_CSharpKeyword.publicKeyword.ESF_FirstAttribute<ESF_AliasTooltipAttribute>().alias;
        }
        else if (!_property.PropertyType.IsVisible)
        {
            keyword = enESF_CSharpKeyword.internalKeyword.ESF_FirstAttribute<ESF_AliasTooltipAttribute>().alias;
        }
        else
        {
            keyword = enESF_CSharpKeyword.protectedKeyword.ESF_FirstAttribute<ESF_AliasTooltipAttribute>().alias;
        }
        return keyword;
    }

    /// <summary>
    /// 获得属性MethodAttributes
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>MethodAttributes</returns>
    public static MethodAttributes GetCSharpMethodAttributes(this PropertyInfo _property)
    {
        MethodAttributes attr = default;
        if (_property.GetMethod != null)
        {
            attr = _property.GetMethod.Attributes;
        }
        else if (_property.SetMethod != null)
        {
            attr = _property.SetMethod.Attributes;
        }
        return attr;
    }

    /// <summary>
    ///  是否是override
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpOverride(this PropertyInfo _property)
    {
        return _property.IsCSharpAbstract() || _property.IsCSharpVirtual();
    }

    /// <summary>
    ///  是否是Abstract
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpAbstract(this PropertyInfo _property)
    {
        return (_property.GetMethod != null && _property.GetMethod.IsAbstract)
            || (_property.SetMethod != null && _property.SetMethod.IsAbstract)
            || _property.PropertyType.IsAbstract;
    }

    /// <summary>
    ///  是否是Sealed
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpSealed(this PropertyInfo _property)
    {
        return _property.PropertyType.IsSealed;
    }

    /// <summary>
    ///  是否是Protected
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpProtected(this PropertyInfo _property)
    {
        return !_property.PropertyType.IsPrimitive && _property.PropertyType.IsNotPublic;
    }

    /// <summary>
    ///  是否Private
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpPrivate(this PropertyInfo _property)
    {
        return _property.PropertyType.IsPrimitive;
    }

    /// <summary>
    ///  是否Public
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpPublic(this PropertyInfo _property)
    {
        return _property.PropertyType.IsPublic;
    }

    /// <summary>
    ///  是否是Virtual
    /// </summary>
    /// <param name="_property">属性</param>
    /// <returns>true:是,false:否</returns>
    public static bool IsCSharpVirtual(this PropertyInfo _property)
    {
        return (_property.GetMethod != null && _property.GetMethod.IsVirtual) || (_property.SetMethod != null && _property.SetMethod.IsVirtual);
    }

    /// <summary>
    /// 获得属性CSharp返回参数类型名称
    /// </summary>
    /// <param name="_method">方法</param>
    /// <returns>CSharp关键字</returns>
    public static string GetCSharpReturnParameterTypeName(this PropertyInfo _property)
    {
        return _property.PropertyType.GetCSharpTypeCode();
    }

    /// <summary>
    /// 获得Interface属性
    /// </summary>
    /// <param name="_type">类型</param>
    /// <param name="_bindFlags">BindingFlags</param>
    /// <param name="_includeInheritInterface">是否包含继承Interface</param>
    /// <returns>属性</returns>
    public static List<PropertyInfo> GetRecursionProperties(this Type _type,
        BindingFlags _bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
        bool _includeInheritInterface = false)
    {
        List<PropertyInfo> result = new List<PropertyInfo>();
        PropertyInfo[] rst = _type.GetProperties();
        if (rst != null && rst.Length > 0)
        {
            result.AddRange(rst);
        }
        if (_type.IsInterface)
        {
            Type[] types = _type.GetInterfaces();
            if (types != null && types.Length > 0)
            {
                foreach (var t in types)
                {
                    var sub = t.GetRecursionProperties(_bindFlags, _includeInheritInterface);
                    if (sub != null && sub.Count > 0)
                    {
                        result.AddRange(sub);
                    }
                }
            }
        }
        return result;
    }
}
#endif